package me.zhengjie.modules.other.rest;

import com.qiaofang.applet.constants.FirstEstateSaleStautsConstant;
import com.qiaofang.applet.constants.UpDownFlagConstants;
import com.qiaofang.applet.service.member.domain.Employee;
import com.qiaofang.applet.service.member.service.EmployeeService;
import com.qiaofang.applet.service.other.service.CityCompanyService;
import com.qiaofang.applet.service.other.service.ProvinceCityService;
import com.qiaofang.applet.service.other.service.dto.CityDesDto;
import com.qiaofang.applet.service.property.domain.Estate;
import com.qiaofang.applet.service.property.domain.FirsthandEstate;
import com.qiaofang.applet.service.property.domain.Property;
import com.qiaofang.applet.service.property.service.DistrictService;
import com.qiaofang.applet.service.property.service.EstateService;
import com.qiaofang.applet.service.property.service.FirsthandEstateService;
import com.qiaofang.applet.service.property.service.PropertyService;
import com.qiaofang.applet.service.property.service.dto.*;
import com.qiaofang.applet.service.property.service.mapstruct.FirsthandEstateMapper;
import com.qiaofang.applet.service.property.service.mapstruct.PropertyMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.annotation.AnonymousAccess;
import me.zhengjie.modules.other.service.dto.*;
import me.zhengjie.modules.system.service.UserService;
import me.zhengjie.utils.SecurityUtils;
import me.zhengjie.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author QF2019
 */
@Slf4j
@RestController
@Api(tags = "其它：房源查询")
@RequestMapping("/api/property")
public class PropertyController {

    @Autowired
    private PropertyService propertyService;

    @Autowired
    private PropertyMapper propertyMapper;

    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private DistrictService districtService;

    @Autowired
    private CityCompanyService cityCompanyService;

    @Autowired
    private FirsthandEstateService firsthandEstateService;

    @Autowired
    private FirsthandEstateMapper firsthandEstateMapper;

    @Autowired
    private ProvinceCityService provinceCityService;

    @Autowired
    private EstateService estateService;

    @Autowired
    private UserService userService;

    @GetMapping("searchSaleProperty")
    @ApiOperation("查询出售房源")
    public ResponseEntity<Page<SalePropertyListAdminDto>> searchSaleProperty(SalePropertyAdminQueryDto salePropertyQueryDto, Pageable pageable) {
        salePropertyQueryDto.setCorporationCode(SecurityUtils.getCorporationCode());
        salePropertyQueryDto.setValidStatus(true);
        salePropertyQueryDto.setCityCodes(userService.getCityCodeList(SecurityUtils.getCurrentUsername()));
        Page<Property> propertyPage;
        if (salePropertyQueryDto.getRecommend() != null && salePropertyQueryDto.getRecommend()) {
            propertyPage = propertyService.findAllHotSaleByParams(salePropertyQueryDto, pageable);
        }else {
            propertyPage = propertyService.findAllSaleByParams(salePropertyQueryDto, pageable);
        }
        Page<SalePropertyListAdminDto> result = propertyMapper.convertDomainToSalePropertyListAdminDto(propertyPage);

        if (CollectionUtils.isEmpty(result.getContent())) {
            return ResponseEntity.ok(result);
        }

        // 查询员工电话
        Map<String, String> employeeMap = this.getEmployeeMobilePhone(salePropertyQueryDto.getCorporationCode(), result);
        // 城市列表
        Map<String, String> cityMap = cityCompanyService.getCityMap(salePropertyQueryDto.getCorporationCode());
        for (SalePropertyListAdminDto dto : result.getContent()) {
            dto.setMobilePhone(employeeMap.get(dto.getCompanyUuid() + "_" + dto.getEmployeeUuid1()));
            dto.setCityName(cityMap.get(dto.getCityCode()));
        }
        return ResponseEntity.ok(result);
    }

    @GetMapping("/searchRentProperty")
    @ApiOperation(value = "查询租房列表", notes = "查询租房列表")
    public ResponseEntity<Page<RentPropertyListAdminDto>> searchRentProperty(RentPropertyAdminQueryDto rentPropertyQueryDto, Pageable pageable) {
        rentPropertyQueryDto.setCorporationCode(SecurityUtils.getCorporationCode());
        rentPropertyQueryDto.setValidStatus(true);
        rentPropertyQueryDto.setCityCodes(userService.getCityCodeList(SecurityUtils.getCurrentUsername()));
        Page<Property> propertyPage;
        if (rentPropertyQueryDto.getRecommend() != null && rentPropertyQueryDto.getRecommend()) {
            propertyPage = propertyService.findAllHotRentByParams(rentPropertyQueryDto, pageable);
        }else {
            propertyPage = propertyService.findAllRentByParams(rentPropertyQueryDto, pageable);
        }
        Page<RentPropertyListAdminDto> result = propertyMapper.convertDomainToRentPropertyListAdminDto(propertyPage);
        if (CollectionUtils.isEmpty(result.getContent())) {
            return ResponseEntity.ok(result);
        }

        // 城市列表
        Map<String, String> cityMap = cityCompanyService.getCityMap(rentPropertyQueryDto.getCorporationCode());
        for (SalePropertyListAdminDto dto : result.getContent()) {
            dto.setCityName(cityMap.get(dto.getCityCode()));
        }
        return ResponseEntity.ok(result);
    }

    @GetMapping("/searchFirstHand")
    @ApiOperation(value = "查询新房楼盘", notes = "查询新房楼盘")
    @AnonymousAccess
    public ResponseEntity<Page<FirsthandEstateAdminListDto>> searchFirstHand(FirsthandEstateAdminQueryDto firsthandEstateQueryDto, Pageable pageable) {
        firsthandEstateQueryDto.setCorporationCode(SecurityUtils.getCorporationCode());
        String saleStatus[] = {FirstEstateSaleStautsConstant.SALE_STATUS_1,FirstEstateSaleStautsConstant.SALE_STATUS_2,
                FirstEstateSaleStautsConstant.SALE_STATUS_3,FirstEstateSaleStautsConstant.SALE_STATUS_4,FirstEstateSaleStautsConstant.SALE_STATUS_5};
        firsthandEstateQueryDto.setSaleStatusList(Arrays.asList(saleStatus));

        firsthandEstateQueryDto.setCityCodes(userService.getCityCodeList(SecurityUtils.getCurrentUsername()));
        Page<FirsthandEstate> page;
        if (firsthandEstateQueryDto.getRecommend() != null && firsthandEstateQueryDto.getRecommend()) {
            page = firsthandEstateService.findAllHotFirsthandByParams(firsthandEstateQueryDto, pageable);
        }else {
            page = firsthandEstateService.findAllByParams(firsthandEstateQueryDto, pageable);
        }
        List<FirsthandEstateAdminListDto> content = new ArrayList<>();
        if (page.getTotalElements() > 0) {
            content = page.getContent().parallelStream().map(firsthandEstateMapper::domainToAdminListDto).collect(Collectors.toList());
        }
        return ResponseEntity.ok(PageableExecutionUtils.getPage(content, page.getPageable(), () -> page.getTotalElements()));
    }

    @PostMapping("/getDistrictAndArea")
    @ApiOperation(value = "城区商圈列表", notes = "城区商圈列表")
    public ResponseEntity<List<DistrictAreaDto>> getDistrictAndArea(@RequestBody @Valid CityQueryDto cityQueryDto) {
        String corporationCode = SecurityUtils.getCorporationCode();
        return ResponseEntity.ok(districtService.findAllDistrictAndArea(corporationCode, cityQueryDto.getCityCode()));
    }


    @PostMapping("/getFirstCityList")
    @ApiOperation(value = "新房城市列表", notes = "新房城市列表")
    public ResponseEntity<List<CityDesDto>> getFirstCityList() {
        List<String> cityCodeList = userService.getCityCodeList(SecurityUtils.getCurrentUsername());
        List<CityDesDto> firstHandCityAndArea = provinceCityService.getFirstHandCity(SecurityUtils.getCorporationCode(), cityCodeList);
        return ResponseEntity.ok(firstHandCityAndArea);
    }

    @PostMapping("/getFirstAreaList")
    @ApiOperation(value = "新房城市区域列表", notes = "新房城市区域列表")
    public ResponseEntity<List<DistrictDto>> getFirstAreaList(@RequestBody @Valid CityQueryDto cityQueryDto) {
        List<DistrictDto> firstHandArea = provinceCityService.getFirstHandArea(cityQueryDto.getCityCode());
        return ResponseEntity.ok(firstHandArea);
    }

    @PutMapping
    @ApiOperation(value = "更新房源状态（主推/上/下架）", notes = "更新房源状态（主推/上/下架）")
    public ResponseEntity<Object> updatePropertyStauts(@RequestBody @Valid SavePropertyStatusDto savePropertyStatusDto) {
        Optional<Property> optional = propertyService.findById(savePropertyStatusDto.getId());
        if (optional.isPresent()) {
            Property property = optional.get();
            String upDownFlag = savePropertyStatusDto.getUpDownFlag();
            String tradeType = property.getTradeType();
            String estateUniqueUuid = property.getEstateUniqueUuid();
            if (StringUtils.isNotEmpty(upDownFlag) && StringUtils.isNotEmpty(tradeType) && !upDownFlag.equals(property.getUpDownFlag())) {
                updateSaleRentNum(upDownFlag, tradeType, estateUniqueUuid);
                //手动上架记录上架时间，7天内不能刷新状态
                if (UpDownFlagConstants.UP_FLAG.getValue().equals(upDownFlag)){
                    property.setManualUpTime(new Date());
                }
                log.info("手动操作了该房源:{},的上下架状态,此次对房源状态修改为:{}==>{},操作人:{}", property.getPropertyUniqueUuid(), property.getUpDownFlag(),
                        upDownFlag, SecurityUtils.getCurrentUsername());
            }
            property.setRecommend(savePropertyStatusDto.getRecommend());
            property.setRecommendSort(savePropertyStatusDto.getRecommend() ? 1 : null);
            property.setUpDownFlag(upDownFlag);
            propertyService.save(property);
        }
        return new ResponseEntity<>(HttpStatus.OK);
    }

    private void updateSaleRentNum(String upDownFlag, String tradeType, String estateUniqueUuid) {
        Estate estate = estateService.findByEstateUniqueUuid(estateUniqueUuid);
        if (estate == null) {
            return;
        }
        if ("上架".equals(upDownFlag)) {
            if ("出售".equals(tradeType)) {
                estate.setSaleNum(estate.getSaleNum() + 1);
            } else if ("出租".equals(tradeType)) {
                estate.setRentNum(estate.getRentNum() + 1);
            } else if ("租售".equals(tradeType)) {
                estate.setSaleNum(estate.getSaleNum() + 1);
                estate.setRentNum(estate.getRentNum() + 1);
            }
        } else {
            if ("出售".equals(tradeType)) {
                estate.setSaleNum(estate.getSaleNum() - 1);
            } else if ("出租".equals(tradeType)) {
                estate.setRentNum(estate.getRentNum() - 1);
            } else if ("租售".equals(tradeType)) {
                estate.setSaleNum(estate.getSaleNum() - 1);
                estate.setRentNum(estate.getRentNum() - 1);
            }
        }
        estateService.save(estate);
    }

    @PutMapping("updateFirstHandlePropertyStauts")
    @ApiOperation(value = "更新新房状态（主推/上/下架）", notes = "更新新房状态（主推/上/下架）")
    public ResponseEntity<Object> updateFirstHandlePropertyStauts(@RequestBody @Valid SavePropertyStatusDto savePropertyStatusDto) {
        Optional<FirsthandEstate> optional = firsthandEstateService.findById(savePropertyStatusDto.getId());
        if (!optional.isPresent()) {
            return new ResponseEntity<>(HttpStatus.OK);
        }
        FirsthandEstate estate = new FirsthandEstate();
        estate.setId(savePropertyStatusDto.getId());
        estate.setRecommend(savePropertyStatusDto.getRecommend());
        estate.setRecommendSort(savePropertyStatusDto.getRecommend() ? 1 : null);
        estate.setUpDownFlag(savePropertyStatusDto.getUpDownFlag());
        //手动上架记录上架时间，7天内不能自动刷新状态
        if (UpDownFlagConstants.UP_FLAG.getValue().equals(savePropertyStatusDto.getUpDownFlag()) && !savePropertyStatusDto.getUpDownFlag().equals(optional.get().getUpDownFlag())){
            estate.setManualUpTime(new Date());
            log.info("手动操作了该楼盘:{},的上下架状态,此次对房源状态修改为:{}==>{},操作人:{}", optional.get().getEstateUniqueUuid(), optional.get().getUpDownFlag(),
                    savePropertyStatusDto.getUpDownFlag(), SecurityUtils.getCurrentUsername());
        }
        firsthandEstateService.updateFirsthandEstate(estate);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 更新主推房源排序
     * @param recommendSortDtos
     * @return
     */
    @PostMapping("/updatePropertyRecommendSort")
    @ApiOperation(value = "更新主推房源排序", notes = "更新主推房源排序")
    public ResponseEntity<Object> updatePropertyRecommendSort(@Valid @RequestBody List<SaveRecommendSortDto> recommendSortDtos) {
        Map<String, SaveRecommendSortDto> tMap = recommendSortDtos.stream().collect(Collectors.toMap(SaveRecommendSortDto::getId, a -> a,(k1,k2)->k1));
        List<Property> properties = (List<Property>) propertyService.findAllById(tMap.keySet());
        if(CollectionUtils.isEmpty(properties)) {
            return new ResponseEntity<>(HttpStatus.OK);
        }

        final Date now = new Date();
        properties.forEach(property -> {
            SaveRecommendSortDto dto = tMap.get(property.getId());
            property.setRecommendSort(dto != null && dto.getRecommendSort() != null ? dto.getRecommendSort() : 0);
            property.setUpdateTime(now);
        });

        propertyService.saveAll(properties);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 更新主推一手房源排序
     * @param recommendSortDtos
     * @return
     */
    @PostMapping("/updateFirstHandleRecommendSort")
    @ApiOperation(value = "更新主推一手房源排序", notes = "更新主推一手房源排序")
    public ResponseEntity<Object> updateFirstHandleRecommendSort(@Valid @RequestBody List<SaveRecommendSortDto> recommendSortDtos) {
        Map<String, SaveRecommendSortDto> tMap = recommendSortDtos.stream().collect(Collectors.toMap(SaveRecommendSortDto::getId, a -> a,(k1,k2)->k1));
        List<FirsthandEstate> properties = (List<FirsthandEstate>) firsthandEstateService.findAllById(tMap.keySet());
        if(CollectionUtils.isEmpty(properties)) {
            return new ResponseEntity<>(HttpStatus.OK);
        }

        final Date now = new Date();
        properties.forEach(property -> {
            SaveRecommendSortDto dto = tMap.get(property.getId());
            property.setRecommendSort(dto != null && dto.getRecommendSort() != null ? dto.getRecommendSort() : 0);
            property.setUpdateTime(now);
        });

        firsthandEstateService.saveAll(properties);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 获取员工手机号码
     *
     * @param corporationCode
     * @param result
     * @return
     */
    private Map<String, String> getEmployeeMobilePhone(String corporationCode, Page<SalePropertyListAdminDto> result) {
        Map<String, String> employeeMap = new HashMap<>();
        List<String> employeeUuids = result.getContent().parallelStream().map(dto -> dto.getEmployeeUuid1()).collect(Collectors.toList());
        List<Employee> employees = employeeService.findAllByEmployeeUuidIn(corporationCode, employeeUuids);
        if (!CollectionUtils.isEmpty(employees)) {
            for (Employee employee : employees) {
                employeeMap.put(employee.getCompanyUuid() + "_" + employee.getEmployeeUuid(), employee.getMobilePhone());
            }
        }
        return employeeMap;
    }
}
